module AboutYou
  module SDK
    module Model
      ###
      # This class represents a product search result model
      ###
      class ProductSearchResult
        # Array of instances of AboutYou::SDK::Model::Product
        attr_accessor :products
        # String page hash
        attr_accessor :page_hash
        # Integer count of products
        attr_accessor :product_count
        # Integer count of products in sale
        attr_accessor :sale_counts
        # Array containing instances of AboutYou::SDK::Model::PriceRange
        attr_accessor :price_ranges
        # Array containing instances of AboutYou::SDK::Model::Facet
        attr_accessor :facets
        # Array containing instances of AboutYou::SDK::Model::Category
        attr_accessor :categories
        # raw facets
        attr_accessor :raw_facets

        ###
        # Constructor for the AboutYou::SDK::Model::ProductSearchResult class
        #
        # * *Returns* :
        #   - an instance of AboutYou::SDK::Model::ProductSearchResult
        ###
        def initialize
          self.products = {}

          self
        end

        ###
        # This method is used for creating an instance of this class by a json_object.
        #
        # * *Args*    :
        #   - +json_object+ -> the json_object received from the api
        #   - +factory+ -> instance of AboutYou::SDK::Factory::DefaultModelFactory
        #
        # * *Returns* :
        #   - Instance of AboutYou::SDK::Model::ProductSearchResult
        ###
        def self.create_from_json(json_object, factory)
          product_search_result = new

          product_search_result.page_hash     = json_object['page_hash']
          product_search_result.product_count = json_object['product_count']
          product_search_result.raw_facets    = json_object['facets']

          json_object['products'].each do |json_product|
            product = factory.create_product(json_product)
            product_search_result.products[product.id] = product
          end

          product_search_result.parse_facets(json_object['facets'], factory)
          # free memory
          json_object['categories'] = nil
          json_object['prices'] = nil
          json_object['sale'] = nil

          product_search_result.facets = factory.create_facets_counts(
            json_object
          )

          product_search_result
        end

        ###
        # This method is used for parsing the facets of the search result
        #
        # * *Args*    :
        #   - +json_object+ -> the json_object received from the api
        #   - +factory+ -> instance of AboutYou::SDK::Factory::DefaultModelFactory
        ###
        def parse_facets(json_object, factory)
          self.categories = factory.create_categories_facets(
            json_object['categories']
          ) if json_object['categories']

          self.price_ranges = factory.create_price_ranges(
            json_object['prices']
          ) if json_object['prices']

          self.sale_counts = factory.create_sale_facet(
            json_object['sale']
          ) if json_object['sale']
        end

        ###
        # Getter for the min price
        #
        # * *Returns*    :
        #   - nil / Integer
        ###
        def min_price
          return nil if price_ranges.empty?

          price_ranges.each do |price_range|
            next if price_range.product_count == 0
            return price_range.min
          end

          price_ranges[0].min
        end

        ###
        # Getter for the max price
        #
        # * *Returns*    :
        #   - nil / Integer
        ###
        def max_price
          return nil if price_ranges.empty?

          price_ranges.reverse_each do |price_range|
            next if price_range.product_count == 0
            return price_range.max
          end

          price_ranges[-1].max
        end

        ###
        # Getter for the category tree
        #
        # * *Returns*    :
        #   - [] / Array containing instances of AboutYou::SDK::Model::Category
        ###
        def category_tree
          top_level_categories = []
          categories.each do |category|
            top_level_categories.push(category) if category.parent.nil?
          end

          top_level_categories
        end
      end
    end
  end
end
